package com.twu.biblioteca;

import java.util.Scanner;

public class BibliotecaApp {

  public Biblioteca bibliotecaLogic;
  private static BibliotecaApp app;

  public static void main(String[] args) {
    setupBibliotecaApp();
    app.startTheApplication();
  }

  /**
   * the method init the app and sets up its logic class.
   */
  private static void setupBibliotecaApp(){
    app = new BibliotecaApp();
    String pathToFile = System.getProperty("user.dir");
    pathToFile = pathToFile + "/data";
    String fileName = "dummyBookList.text";
    app.bibliotecaLogic = new Biblioteca();
    app.bibliotecaLogic.setBooksFileName(fileName);
    app.bibliotecaLogic.setFilePath(pathToFile);
    app.bibliotecaLogic.setMoviesFileName("dummyMovieList.text");
  }

  // Instance methods
  public void startTheApplication(){
    System.out.println("============================");
    System.out.println(getWelcomeMessage());
    System.out.println("============================\n");

    while (true) {
      System.out.println("Application Menu:\n" + showMenu());
      int selectedOption = promptUserForOption();
      while (!chooseOption(selectedOption)) {
        System.out.println("Wrong option, try again\n");
        System.out.println("Application Menu:\n" + showMenu());
        selectedOption = promptUserForOption();
      }
      printSelectedOption(selectedOption);
    }
  }

  /**
   * Prompt the user for input for the mune
   * @return the user chosen input
   */
  private int promptUserForOption(){
    Scanner inputScanner = new Scanner(System.in);
    System.out.print("Type Option number: ");

    while (!inputScanner.hasNextInt()){
      inputScanner.next();
      System.out.println("***Invalid Input! Only option number is allowed***\n");
      System.out.println("Application Menu:\n" + showMenu());
      System.out.print("Type Option number: ");
    }

    return inputScanner.nextInt();
  }

  public String getWelcomeMessage(){
    return "Hi! Welcome to BibliotecaApp";
  }

  /**
   * Gets the available books, and format them for printing
   * @return formatted string of table of books
   */
  public String listBooks(){
    Book[] booksToList = bibliotecaLogic.listBooks();
    String formatter =  "|%-25s | %-20s | %-16s|\n";
    String output = String.format(formatter, "Book Title", "Author", "Publication Year");
    output = output + "|--------------------------|----------------------|-----------------|\n";
    for (Book book: booksToList){
      output = output + String.format(formatter, book.bookTitle, book.author, book.publicationYear);
    }
    output = output + " ------------------------------------------------------------------- \n";
    return output;
  }

  public String listMovies(){
    Movie[] moviesToList = bibliotecaLogic.listMovies();
    String formatter = "|%-25s | %-20s | %-16s| %-16s|\n";
    String output = String.format(formatter, "Movie Name", "Director", "Release Year", "Rating");
    output = output + "|--------------------------|----------------------|-----------------|-----------------|\n";
    for (Movie movie: moviesToList){
      String rating = movie.rating == 0? "unrated":""+movie.rating;
      output = output + String.format(formatter, movie.movieName, movie.director, movie.releaseYear, rating);
    }
    output = output + " ------------------------------------------------------------------------------------- \n";
    return output;
  }

  /**
   * formatted list of options
   * @return formatted string of menu options
   */
  public String showMenu(){
    return  "1: List Books\n" +
            "2: List Movies\n" +
            "3: Checkout Book\n" +
            "4: Return Book\n" +
            "5: Checkout Movie\n" +
            "6: Quit Application\n";
  }


  public String scanInputString(String message){
    Scanner inputScanner = new Scanner(System.in);
    System.out.print(message);
    return inputScanner.nextLine();
  }

  public void handleCheckoutMovieOption(){
    String movieName = scanInputString("Type the name of movie: ").trim();
    Movie aMovie = bibliotecaLogic.getMovieByName(movieName);
    if (bibliotecaLogic.checkoutMovie(aMovie)){
      System.out.println("Thank you! Enjoy the Movie!");
    } else{
      System.out.println("Unsuccessful Checkout: That movie is not available.\n\n");
    }
  }
  public void handleCheckoutOption(){
    String bookName = scanInputString("Type the name of the book: ").trim();
    Book aBook = bibliotecaLogic.getBookByName(bookName);
    if (bibliotecaLogic.checkoutBook(aBook)){
      System.out.println("Thank you! Enjoy the book\n\n");
    } else{
      System.out.println("Unsuccessful Checkout: That book is not available.\n\n");
    }
  }

  public void handleReturnOption(){
    String bookName = scanInputString("Type the name of the book: ").trim();
    Book aBook = bibliotecaLogic.getBookByName(bookName);
    if (bibliotecaLogic.returnBook(aBook)){
      System.out.println("Thank you for returning the book\n\n");
    } else{
      System.out.println("Unsuccessful Return: That is not a valid book to return.\n\n");
    }
  }

  /**
   * Determines wether the selected option is valid or not
   * @param option the mune option
   * @return true if the option is valid, false otherwise
   */
  public boolean chooseOption(int option){
    return option == 1 || option == 2 || option == 3 || option == 4 || option == 5 || option == 6;
  }

  /**
   * Prints the mune of the selected option
   * @param option the selected option
   */
  public void printSelectedOption(int option){
    switch (option) {
      case 1:
        System.out.println(listBooks());
        break;
      case 2:
        System.out.println(listMovies());
         break;
      case 3:
        handleCheckoutOption();
        break;
      case 4:
        handleReturnOption();
        break;
      case 5:
        handleCheckoutMovieOption();
         break;
      case 6:
        System.exit(0);
        break;
      default:
        System.out.println("No output for the selected option");
    }
  }
}
